#include "stdafx.h"
#include "gp_Ax2d.h"
#include "gp_Ax22d.h"
#include "gp_Pnt2d.h"
#include "gp_Trsf2d.h"
#include "gp_Vec2d.h"
#include "gp_Circ2d.h"
#include "gp.h"


 gp_Circ2d::gp_Circ2d () : radius(DBL_MAX)
{ }

 gp_Circ2d::gp_Circ2d (const gp_Ax2d& XAxis, 
			     const double Radius,
			     const bool Sense) : radius(Radius)
{
  Standard_ConstructionError_Raise_if(Radius < 0.0,"");
  pos = gp_Ax22d(XAxis,Sense);
}

 gp_Circ2d::gp_Circ2d (const gp_Ax22d&     Axis, 
			     const double Radius) :
			     pos(Axis),
			     radius(Radius)
{
	 Standard_ConstructionError_Raise_if(Radius < 0.0, "");
}

 void gp_Circ2d::SetLocation (const gp_Pnt2d& P)
{ pos.SetLocation (P); }

 void gp_Circ2d::SetXAxis (const gp_Ax2d& A)
{  pos.SetXAxis(A); }

 void gp_Circ2d::SetAxis (const gp_Ax22d& A)
{  pos.SetAxis(A);}

 void gp_Circ2d::SetYAxis (const gp_Ax2d& A)
{   pos.SetYAxis(A); }

 void gp_Circ2d::SetRadius (const double Radius)
{ 
	 Standard_ConstructionError_Raise_if(Radius < 0.0, "");
  radius = Radius;
}

   double gp_Circ2d::Area() const
{ return M_PI * radius * radius; }

 void gp_Circ2d::Coefficients (double& A,
				     double& B,
				     double& C,
				     double& D,
				     double& E,
				     double& F) const
{
  double Xc = pos.Location().X();
  double Yc = pos.Location().Y();
  A = 1.0;
  B = 1.0;
  C = 0.0;
  D = - Xc;
  E = - Yc;
  F = Xc * Xc + Yc * Yc - radius * radius;
}

 bool gp_Circ2d::Contains
(const gp_Pnt2d& P,
 const double LinearTolerance) const
{ return Distance(P) <= LinearTolerance; }

 double gp_Circ2d::Distance (const gp_Pnt2d& P) const
{
  gp_XY Coord = P.XY();
  Coord.Subtract (pos.Location().XY());
  double D = radius - Coord.Modulus();
  if (D < 0) D = - D;
  return D;
}

 double gp_Circ2d::SquareDistance (const gp_Pnt2d& P) const
{
  gp_XY Coord = P.XY();
  Coord.Subtract (pos.Location().XY());        
  double D = radius - Coord.Modulus();
  return D * D;
}

   double gp_Circ2d::Length() const
{ return 2. * M_PI * radius; }

 const gp_Pnt2d& gp_Circ2d::Location () const
{return pos.Location(); }

   double gp_Circ2d::Radius() const
{ return radius; }

   const gp_Ax22d& gp_Circ2d::Axis () const
{ return pos; }

   const gp_Ax22d& gp_Circ2d::Position () const
{ return pos; }

 gp_Ax2d gp_Circ2d::XAxis () const
{ return gp_Ax2d (pos.XAxis()); }

 gp_Ax2d gp_Circ2d::YAxis () const
{ return gp_Ax2d (pos.YAxis()); }

 void gp_Circ2d::Reverse() 
{
  gp_Dir2d Temp = pos.YDirection ();
  Temp.Reverse ();
  pos.SetAxis(gp_Ax22d(pos.Location(),pos.XDirection(),Temp));
}

 gp_Circ2d gp_Circ2d::Reversed() const
{
  gp_Circ2d C = *this;
  gp_Dir2d Temp = pos.YDirection ();
  Temp.Reverse ();
  C.pos.SetAxis(gp_Ax22d(pos.Location(),pos.XDirection(),Temp));
  return C;
}

 bool gp_Circ2d::IsDirect() const
{ return (pos.XDirection().Crossed(pos.YDirection())) >= 0.0; }

 void gp_Circ2d::Rotate (const gp_Pnt2d& P,
			       const double Ang)
{pos.Rotate (P, Ang);}

 gp_Circ2d gp_Circ2d::Rotated (const gp_Pnt2d& P,
				     const double Ang) const
{
  gp_Circ2d C = *this;
  C.pos.Rotate (P, Ang);
  return C; 
}

 void gp_Circ2d::Scale (const gp_Pnt2d& P,
			      const double S)
{ 
  radius *= S;
  if (radius < 0) radius = - radius;
  pos.Scale(P, S);
}

 gp_Circ2d gp_Circ2d::Scaled (const gp_Pnt2d& P,
				    const double S) const
{
  gp_Circ2d C = *this;
  C.radius *= S;
  if (C.radius < 0) C.radius = - C.radius;
  C.pos.Scale(P, S);
  return C; 
}

 void gp_Circ2d::Transform (const gp_Trsf2d& T)
{
  radius *= T.ScaleFactor();
  if (radius < 0) radius = - radius;
  pos.Transform(T);
}

 gp_Circ2d gp_Circ2d::Transformed (const gp_Trsf2d& T) const
{
  gp_Circ2d C = *this;
  C.radius *= T.ScaleFactor();
  if (C.radius < 0) C.radius = - C.radius;
  C.pos.Transform(T);
  return C;
}

 void gp_Circ2d::Translate (const gp_Vec2d& V)
{ pos.Translate(V); }

 gp_Circ2d gp_Circ2d::Translated (const gp_Vec2d& V) const
{
  gp_Circ2d C = *this;
  C.pos.Translate(V);
  return C; 
}

 void gp_Circ2d::Translate (const gp_Pnt2d& P1,
				  const gp_Pnt2d& P2)
{ pos.Translate(P1, P2); }

 gp_Circ2d gp_Circ2d::Translated (const gp_Pnt2d& P1,
					const gp_Pnt2d& P2) const
{
  gp_Circ2d C = *this;
  C.pos.Translate(P1, P2);
  return C; 
}
 void gp_Circ2d::Mirror (const gp_Pnt2d& P)
 { pos.Mirror(P); }

 gp_Circ2d gp_Circ2d::Mirrored (const gp_Pnt2d& P) const
 {
	 gp_Circ2d C = *this;
	 C.pos.Mirror (P);
	 return C; 
 }

 void gp_Circ2d::Mirror (const gp_Ax2d& A)
 { pos.Mirror (A); }

 gp_Circ2d gp_Circ2d::Mirrored (const gp_Ax2d& A) const
 {
	 gp_Circ2d C = *this;
	 C.pos.Mirror (A);
	 return C; 
 }


